#ifndef UID_STACK_H
#define UID_STACK_H

#include "uid.h"

//Macros to make reusing easier later on
#define STACK_STRUCT_NAME uidstack_s
#define STACK_TYPE uidstack_t
#define STACK_ELEMENT uid_t

#define STACK_PUSH_FUNC pushUID
#define STACK_POP_FUNC popUID

#define STACK_EMPTY_FUNC emptyUIDStack
#define STACK_EMPTY_PRED isEmptyUIDStack

#define STACK_FREE_FUNC freeUIDStack

#define STACK_SEARCH_FUNC linearSearchUID
#define STACK_REMOVE_FUNC linearRemoveUID

struct STACK_STRUCT_NAME;

typedef struct STACK_STRUCT_NAME* STACK_TYPE;

STACK_TYPE STACK_PUSH_FUNC(STACK_ELEMENT elt, STACK_TYPE stack);
STACK_TYPE STACK_POP_FUNC(STACK_ELEMENT* elt, STACK_TYPE stack);

STACK_TYPE STACK_EMPTY_FUNC(void);
int        STACK_EMPTY_PRED(STACK_TYPE stack);

void STACK_FREE_FUNC(STACK_TYPE stack);

/* WARNING: These may be depricated if we need some
 * faster structure for the reserved UIDs */
int        STACK_SEARCH_FUNC(STACK_ELEMENT elt, STACK_TYPE stack);
STACK_TYPE STACK_REMOVE_FUNC(STACK_ELEMENT elt, STACK_TYPE stack);

//TODO: Make this go away :(
#define INITIALISE_STATIC_EMPTY_UID_STACK (uidstack_t) 0

/* Remove macros to free up namespace unless imported
 * unless we're being included by the implementation */
#ifndef KEEP_TYPE_MACROS
#undef STACK_STRUCT_NAME
#undef STACK_TYPE
#undef STACK_ELEMENT

#undef STACK_PUSH_FUNC
#undef STACK_POP_FUNC

#undef STACK_EMPTY_FUNC
#undef STACK_EMPTY_PRED

#undef STACK_FREE_FUNC

#undef STACK_SEARCH_FUNC
#undef STACK_REMOVE_FUNC
#endif

#endif
